﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.CodeDom.Compiler;
using System.Xml;
using System.Collections;
using System.CodeDom;
using System.Threading;
using System.Reflection;

namespace CodeEditor
{
    public partial class Editor : DigitalRune.Windows.Docking.DockableForm
    {
        public event ThreadExceptionEventHandler ExceptionThrown;

        ErrorWindow errorWindow = new ErrorWindow(); //Anzeige für Kompilerfehler
        MethodWindow mainMethodForm = new MethodWindow(true,true); //EditorFenster für den Einstiegspunkt
        MethodListForm methodListForm = new MethodListForm(); //Listenfenster für die Methoden
        MethodWindow currentMethodForm = new MethodWindow(false,true); //aktuelles Editorfenster, für die Bearbeitungstools...
        String currentFileName = ""; //Dateiname unter dem gespeichert wird
        List<object> moduleList = new List<object>();
        CSharpCompiler.Compiler cSharpCompiler = new CSharpCompiler.Compiler(); //Compiler
        
        //GraphViewer wird als Parameter an das delegate übergeben, um im Code darauf zugreifen zu können
        //Parameter sind in der Compilerklasse definiert

        //delegate void RunDelegate(params object[] objects);
        //delegate void RunDelegate();
        
        Object compiledInstance = null;
        //RunDelegate runDel = null; //delegate für das auszuführende script
        Thread runDelegateThread; //thread, in dem der delegate läuft
        bool bNormalRun = false; //Für das richtige Ausgrauen der Steuerelemente
        bool bCompiled = false;
        /// <summary>
        /// Konstruktor des Editors. Hier werden alle Fenster angelegt und dem Editor beigefügt.
        /// Außerdem werden hier Events und der Compiler definiert.
        /// </summary>
        /// 


        private int userLevel;
        public int UserLevel
        {
            set
            {
                userLevel = value;
                methodListForm.UserLevel = value;
                switch (value)
                {
                    case 1: //admin
                        methodListForm.Enabled = true;
                        menuBearbeiten.Enabled = true;
                        menuDateiSpeichern.Enabled = menuDateiSpeichernUnter.Enabled = true;
                        menuDateiNeu.Enabled = true;
                        toolStripEditor.Enabled = true;
                        toolStripFile.Enabled = true;
                        mainMethodForm.Enabled = true;
                        foreach (var key in methodListForm.NodesAndEditorWindows.Keys)
                        {

                            (methodListForm.NodesAndEditorWindows[key] as MethodWindow).Enabled = true;
                        }
                        break;
                    case 2:
                    case 3: //alle anderen
                        methodListForm.Enabled = false;
                        menuBearbeiten.Enabled = false;
                        menuDateiSpeichern.Enabled = menuDateiSpeichernUnter.Enabled = false;
                        menuDateiNeu.Enabled = false;
                        toolStripFile.Enabled = false;
                        toolStripEditor.Enabled = false;
                        mainMethodForm.Enabled = false;
                        foreach (var key in methodListForm.NodesAndEditorWindows.Keys)
                        {

                            (methodListForm.NodesAndEditorWindows[key] as MethodWindow).Enabled = false;
                        }
                        break;
                }
            }
            get
            {
                return userLevel;
            }
        }

        public Editor()
        {
            InitializeComponent();
            
            
            editorDockPanel.ActiveDocumentChanged += new EventHandler(editorDockPanel_ActiveDocumentChanged);

            //Fenster erstellen und anzeigen:
            errorWindow.TabText = Properties.Resources.CompilerResultsTabText;
            errorWindow.AllowUserDocking = false;
            errorWindow.Show(editorDockPanel, DigitalRune.Windows.Docking.DockState.DockBottomAutoHide);

            methodListForm.TabText = Properties.Resources.MethodsTabText;
            methodListForm.AllowUserDocking = false;
            methodListForm.CloseButton = false;
            methodListForm.Show(editorDockPanel, DigitalRune.Windows.Docking.DockState.DockLeftAutoHide);
            methodListForm.EditorWindowAdded += new MethodListForm.EditorWindowEventHandler(methodForm_EditorWindowAdded);
            methodListForm.EditorWindowTextChanged += new EventHandler(methodListForm_EditorWindowTextChanged);
            methodListForm.IsSaved = true;
            
            mainMethodForm.TabText = Properties.Resources.MainMethodTabText;
            mainMethodForm.AllowUserDocking = true;
            mainMethodForm.Show(editorDockPanel, DigitalRune.Windows.Docking.DockState.Document);
            mainMethodForm.Settings.MethodName = "Main";
            mainMethodForm.EditorBox.TextChanged += new EventHandler(EditorBox_TextChanged);

            cSharpCompiler.Usings.Add(new System.CodeDom.CodeNamespaceImport("System"));
            cSharpCompiler.Usings.Add(new System.CodeDom.CodeNamespaceImport("System.Windows.Forms"));

            cSharpCompiler.CompileComplete += new CSharpCompiler.Compiler.CompilerResultsEventHandler(cSharpCompiler_CompileComplete);
            cSharpCompiler.CompileError += new CSharpCompiler.Compiler.CompilerResultsEventHandler(cSharpCompiler_CompileError);



            //Module im Parser registrieren
            //(mainMethodForm.EditorBox.Lexer as QWhale.Syntax.Parsers.CsParser).RegisterObject("Graph", graphViewer);
           
            
            (mainMethodForm.EditorBox.Lexer as QWhale.Syntax.Parsers.CsParser).RegisterAllAssemblies();

            //zuletzt alle Dateien im aktuellen Verzeichnis durchgehen und versuchen als assembly zu registrieren

            //Module sollen nur über das Hauptprgramm dem Skriper bekannt gemacht werden->Nur aus dem Module-Ordner dlls verwenden
            /*
            foreach (String file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory()))
            {
                try
                {
                    System.Reflection.Assembly ass = System.Reflection.Assembly.LoadFile(file);
                    (mainMethodForm.EditorBox.Lexer as QWhale.Syntax.Parsers.CsParser).RegisterAssembly(ass);
                    //DLL dem Compiler hinzufügen

                    Assembly lib = Assembly.LoadFile(file);
                    cSharpCompiler.AddLibrary(lib);

                }
                catch
                {
                    //Datei ist keine Assembly. muss nicht weiter behandelt werden

                }
            }
             */

        }

        public void RegisterModule(object module)
        {
            (mainMethodForm.EditorBox.Lexer as QWhale.Syntax.Parsers.CsParser).RegisterObject((module as Form).Text, module);
            cSharpCompiler.AddModule(module);
            moduleList.Add(module);
        }

        ~Editor()
        {
            //Thread für Codeausführung beenden, falls noch läuft
            if (runDelegateThread != null && runDelegateThread.IsAlive)
            {
                runDelegateThread.Abort();
            }
        }

        public void addLib(Assembly lib)
        {
            (mainMethodForm.EditorBox.Lexer as QWhale.Syntax.Parsers.CsParser).RegisterAssembly(lib);
            cSharpCompiler.AddLibrary(lib);
        }
        
        /// <summary>
        /// Wird bei Klick auf Starten ausgeführt. Hier wird kompiliert und - falls erfolgreich - auch ausgeführt.
        /// </summary>
        /// <param name="sender">Starten - Button</param>
        /// <param name="e">Event Arguments</param>
        private void compilerToolStripRun_Click(object sender, EventArgs e)
        {
            
            //Sollte nicht vorkommen, trotzdem evtl. laufenden Thread anhalten
            if (runDelegateThread != null && runDelegateThread.IsAlive)
            {
                try
                {
                    runDelegateThread.Abort();
                }
                catch
                {
                    //ThreadAbortException - muss nicht behandelt werden
                }
            }
            runDelegateThread = new Thread(new ThreadStart(Run));
            compilerToolStripCompile.Enabled = false;
            compilerToolStripRun.Enabled = false;
            compilerToolStripRunInLoop.Enabled = false;
            compilerToolStripStop.Enabled = true;
            bNormalRun = true;
            runDelegateThread.Start();
        }

        private void compilerToolStripRunInLoop_Click(object sender, EventArgs e)
        {
            compilerToolStripRunInLoop.Enabled = false;
            compilerToolStripRun.Enabled = false;
            compilerToolStripCompile.Enabled = false;
            compilerToolStripStop.Enabled = true;
            backgroundWorkerRunInLoop.RunWorkerAsync();
        }

        private void compilerToolStripCompile_Click(object sender, EventArgs e)
        {
            //CompilerResults zurücksetzen
            errorWindow.Errors = new CompilerErrorCollection();
            errorWindow.DockState = DigitalRune.Windows.Docking.DockState.DockBottomAutoHide;

            //Kompilieren
            cSharpCompiler.MainMethodCode = mainMethodForm.EditorText;
            cSharpCompiler.MemberMethods.Clear();
            foreach (Object key in methodListForm.NodesAndEditorWindows.Keys)
            {
                MethodWindow currentMethod = methodListForm.NodesAndEditorWindows[key] as MethodWindow;

                CodeMemberMethod method = new CodeMemberMethod();
                method.ReturnType = new CodeTypeReference(currentMethod.Settings.ReturnType);
                foreach (var value in currentMethod.Settings.Parameters)
                {
                    method.Parameters.Add(new CodeParameterDeclarationExpression(value.ParameterType, value.ParameterName));
                }
                method.Name = currentMethod.Settings.MethodName;
                method.Statements.Add(new CodeSnippetExpression(currentMethod.EditorText));
                cSharpCompiler.MemberMethods.Add(method);
            }
            cSharpCompiler.Compile();
        }


        private void compilerToolStripStop_Click(object sender, EventArgs e)
        {
            try
            {
                backgroundWorkerRunInLoop.CancelAsync();
                runDelegateThread.Abort();
            }
            catch { }
            finally
            {
                compilerToolStripCompile.Enabled = true;
                compilerToolStripRun.Enabled = true;
                compilerToolStripRunInLoop.Enabled = true;
                compilerToolStripStop.Enabled = false;
            }
        }


        /// <summary>
        /// Event wird ausgelöst, wenn Kompilieren nicht erfolgreich war.
        /// </summary>
        /// <param name="sender">Compiler</param>
        /// <param name="e">erweiterte Event Arguments mit Compilermeldungen</param>
        void cSharpCompiler_CompileError(object sender, CSharpCompiler.CompilerResultsEventArgs e)
        {
            //Fehler beim Kompileren, Fehler im Fehlerfenster darstellen!!
            errorWindow.Errors = e.Results.Errors;
            errorWindow.DockState = DigitalRune.Windows.Docking.DockState.DockBottom;

            compilerToolStripRun.Enabled = false;
            compilerToolStripRunInLoop.Enabled = false;
            compilerToolStripStop.Enabled = false;
            bCompiled = false;
        }

        /// <summary>
        /// Event wird ausgelöst, wenn Kompilieren erfolgreich war.
        /// </summary>
        /// <param name="sender">Compiler</param>
        /// <param name="e">erweiterte Event Arguments mit Compilermeldungen</param>
        void cSharpCompiler_CompileComplete(object sender, CSharpCompiler.CompilerResultsEventArgs e)
        {
            try
            {
                compiledInstance = e.Results.CompiledAssembly.CreateInstance(e.TypeName, true);

                //Thread definieren
                
                compilerToolStripRun.Enabled = true;
                compilerToolStripRunInLoop.Enabled = true;
                compilerToolStripStop.Enabled = false;
                bCompiled = true;
            }
            catch (Exception ex)
            {
                new ExceptionMessageBox(ex);
                ExceptionThrown(this, new ThreadExceptionEventArgs(ex));
            }
        }



        private void backgroundWorkerRunInLoop_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (backgroundWorkerRunInLoop.CancellationPending)
                {
                    break;
                }

                Run();
            }
            compilerToolStripRunInLoop.Enabled = true;
            compilerToolStripRun.Enabled = true;
            compilerToolStripCompile.Enabled = true;
            compilerToolStripStop.Enabled = false;
        }

        private void Run()
        {
            //Thread oder Backgroundworker wurde gestartet
            try
            {
                Type t = compiledInstance.GetType();
                t.InvokeMember("Run", BindingFlags.InvokeMethod, Type.DefaultBinder, compiledInstance, moduleList.ToArray());
            }
            catch (Exception ex)
            {
                new ExceptionMessageBox(ex);
                ExceptionThrown(this, new ThreadExceptionEventArgs(ex));
            }
            if (bNormalRun)
            {  
                //Code wurde nicht in Schleife ausgeführt, Steuerelemente zurücksetzen
                if (this.InvokeRequired)
                {
                    this.Invoke(new Action(ResetControls));
                }
                else
                {
                    ResetControls();
                }
            }
        }

        private void ResetControls()
        {
            compilerToolStripRunInLoop.Enabled = true;
            compilerToolStripRun.Enabled = true;
            compilerToolStripCompile.Enabled = true;
            compilerToolStripStop.Enabled = false;
            bNormalRun = false;
        }

        /// <summary>
        /// wird ausgelöst, wenn Text geändert wird. Bezieht sich nur auf die mainEditorForm!!!
        /// </summary>0
        /// <param name="sender">EditorBox der mainEditorForm</param>
        /// <param name="e">Event Arguments</param>
        void EditorBox_TextChanged(object sender, EventArgs e)
        {
            methodListForm.IsSaved = false;
            compilerToolStripRun.Enabled = false;
            compilerToolStripRunInLoop.Enabled = false;
            compilerToolStripStop.Enabled = false;
            bCompiled = false;
        }

        /// <summary>
        /// wird ausgelöst, wenn Text geändert wird. Bezieht sich auf alle anderen MethodWindows
        /// </summary>
        /// <param name="sender">EditorBox</param>
        /// <param name="e">Event Arguments</param>
        void methodListForm_EditorWindowTextChanged(object sender, EventArgs e)
        {
            EditorBox_TextChanged(sender, e);
        }



        /// <summary>
        /// Wenn eine andere Methode ausgewählt wird, wird currentEditorWindow auf die aktuelle
        /// Methode gesetzt, damit die Menupunkte "Bearbeiten" auf die aktuelle Form angewendet werden
        /// </summary>
        /// <param name="sender">Editordockpanel</param>
        /// <param name="e">Event Arguments</param>
        void editorDockPanel_ActiveDocumentChanged(object sender, EventArgs e)
        {
            try
            {
                //Wird ausgelöst, wenn ein Dokument - sprich eine Methode - gewechselt wird.
                if (editorDockPanel.ActiveDocument.GetType() == typeof(MethodWindow))
                {
                    currentMethodForm = editorDockPanel.ActiveDocument as MethodWindow;
                }
            }
            catch
            {
            }
        }


        /// <summary>
        /// wird ausgelöst, wenn eine neue Methode hinzugefügt wird.
        /// Hier wird die Form dargestellt und das Dockingverhalten definiert.
        /// </summary>
        /// <param name="sender">methodForm</param>
        /// <param name="e">erweiterte Event Arguments mit dem EditorWindow</param>
        void methodForm_EditorWindowAdded(object sender, EditorWindowEventArgs e)
        {
            e.CurrentEditorWindow.EditorBox.SyntaxSettings.LoadFromEdit(mainMethodForm.EditorBox);
            
            //sicherstellen, dass der Parser von der MainMethod übernommen wird
            //wichtig für Autovervollständigung!!!
            e.CurrentEditorWindow.EditorBox.Lexer = mainMethodForm.EditorBox.Lexer;
            e.CurrentEditorWindow.Show(editorDockPanel, DigitalRune.Windows.Docking.DockState.Document);
        }



        #region Menu "Bearbeiten"
        /// <summary>
        /// Wird ausgelöst, wenn das Bearbeiten - Menu angeklickt wird.
        /// </summary>
        /// <param name="sender">menuBearbeiten</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeiten_DropDownOpening(object sender, EventArgs e)
        {
            //Überprüfen, ob einige Steuerelemente ausgeblendet werden müssen:
            menuBearbeienRueckgaengig.Enabled = currentMethodForm.EditorBox.Source.CanUndo();
            menuBearbeitenAusschneiden.Enabled = currentMethodForm.EditorBox.Selection.CanCut();
            menuBearbeitenKopieren.Enabled = currentMethodForm.EditorBox.Selection.CanCopy();
            menuBearbeitenEinfuegen.Enabled = Clipboard.ContainsText();
            menuBearbeitenLoeschen.Enabled = currentMethodForm.EditorBox.Selection.SelectionLength > 0;
            menuBearbeitenWiederholen.Enabled = currentMethodForm.EditorBox.Source.CanRedo();
        }

        /// <summary>
        /// Rückgängig - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeienRueckgaengig_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.Source.Undo();
        }

        /// <summary>
        /// Wiederholen - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenWiederholen_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.Source.Redo();
        }

        /// <summary>
        /// Ausschneiden - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenAusschneiden_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.Selection.Cut();
        }

        /// <summary>
        /// Kopieren - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenKopieren_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.Selection.Copy();
        }

        /// <summary>
        /// Einfügen - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenEinfuegen_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.Selection.Paste();
        }

        /// <summary>
        /// Löschen - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenLoeschen_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Selection.IsEmpty)
            {
                currentMethodForm.EditorBox.Selection.DeleteRight();
            }
            else
            {
                currentMethodForm.EditorBox.Selection.Delete();
            }
        }

        /// <summary>
        /// Suchen - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenSuchen_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.DisplaySearchDialog();
        }

        /// <summary>
        /// Weitersuchen - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenWeitersuchen_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.FindNext();
        }

        /// <summary>
        /// Ersetzen - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenErsetzen_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.DisplayReplaceDialog();
        }

        /// <summary>
        /// WechselnSieZu - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenWechselnSieZu_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.DisplayGotoLineDialog();
        }

        /// <summary>
        /// AllesMarkieren - Funktion
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuBearbeitenAllesMarkieren_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.Selection.SelectAll();
        }
        #endregion

        #region Menu "Datei"

        /// <summary>
        /// Öffnen einer Datei
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuDateiOeffnen_Click(object sender, EventArgs e)
        {
            //Script einlesen
            if (!methodListForm.IsSaved)
            {
                if (MessageBox.Show(Properties.Resources.ScriptNotSavedText, Properties.Resources.ScriptNotsavedHeader, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Yes)
                {
                    Open();
                }
            }
            else
            {
                Open();
            }
        }



        /// <summary>
        /// Speichern einer Datei
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuDateiSpeichern_Click(object sender, EventArgs e)
        {
            if (currentFileName == String.Empty)
            {
                //noch kein Dateiname! "Speichern Unter..." aufrufen
                menuDateiSpeichernUnter_Click(sender, e);
            }
            else
            {
                try
                {
                    WriteCodeToXMLFile(currentFileName);
                }
                catch (Exception ex)
                {
                    new ExceptionMessageBox(ex);
                }
            }
        }

        /// <summary>
        /// Speichern einer Datei unter...
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuDateiSpeichernUnter_Click(object sender, EventArgs e)
        {
            if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                currentFileName = saveFileDialog.FileName;
                try
                {
                    WriteCodeToXMLFile(currentFileName);
                }
                catch (Exception ex)
                {
                    new ExceptionMessageBox(ex);
                }
            }
        }


        /// <summary>
        /// Neues Projekt anlegen
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuDateiNeu_Click(object sender, EventArgs e)
        {
            if (!methodListForm.IsSaved)
            {
                if (MessageBox.Show(Properties.Resources.ScriptNotSavedText, Properties.Resources.ScriptNotsavedHeader, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Yes)
                {
                    New();
                }
            }
            else
            {
                New();
            }
        }

        /// <summary>
        /// Aktuelle Datei drucken
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuDateiDrucken_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Printing.ExecutePrintDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    currentMethodForm.EditorBox.Printing.Print();
                }
                catch (Exception ex)
                {
                    new ExceptionMessageBox(ex);
                }
            }
        }

        /// <summary>
        /// Seite einrichten
        /// </summary>
        /// <param name="sender">Menupunkt</param>
        /// <param name="e">Event Arguments</param>
        private void menuDateiSeiteEinrichten_Click(object sender, EventArgs e)
        {
            currentMethodForm.EditorBox.Printing.PageSetupDialog.ShowDialog();
        }
        #endregion

        #region Hilfsmethoden für wiederkehrende Aufgaben

        /// <summary>
        /// Anlegen eines neuen Projekts. Alle Methoden löschen usw....
        /// </summary>
        private void New()
        {
            try
            {
                methodListForm.ClearAllMethods();
                mainMethodForm.EditorText = String.Empty;
                currentFileName = String.Empty;
                methodListForm.IsSaved = true;
            }
            catch (Exception ex)
            {
                new ExceptionMessageBox(ex);
            }
        }

        /// <summary>
        /// Öffnen einer Datei. AUfgabe wird weitergegeben an XmlParser
        /// </summary>
        private void Open()
        {
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    ReadCodeFromXMLFile(openFileDialog.FileName);
                    currentFileName = openFileDialog.FileName;
                }
                catch (Exception ex)
                {
                    new ExceptionMessageBox(ex);
                }
            }
        }


        /// <summary>
        /// Schreiben einer Datei mit dem XmlParser
        /// </summary>
        /// <param name="fileName">Dateiname</param>
        private void WriteCodeToXMLFile(String fileName)
        {
            XmlDocument myDocument = new XmlDocument();
            myDocument.AppendChild(myDocument.CreateXmlDeclaration("1.0", "iso-8859-1", "yes"));
            XmlNode rootNode = myDocument.CreateElement("root");
            XmlNode mainNode = myDocument.CreateElement("main");
            mainNode.InnerText = mainMethodForm.EditorText;
            rootNode.AppendChild(mainNode);

            Hashtable myMethods = methodListForm.NodesAndEditorWindows;
            foreach (Object key in myMethods.Keys)
            {
                XmlNode methodNode = myDocument.CreateElement("method");
                XmlAttribute methodNameAttribute = myDocument.CreateAttribute("methodName");
                methodNameAttribute.InnerText = (myMethods[key] as MethodWindow).TabText;
                methodNode.Attributes.Append(methodNameAttribute);
                XmlAttribute methodReturnTypeAttribute = myDocument.CreateAttribute("returnType");
                methodReturnTypeAttribute.InnerText = (myMethods[key] as MethodWindow).Settings.ReturnType;
                methodNode.Attributes.Append(methodReturnTypeAttribute);

                XmlNode parametersNode = myDocument.CreateElement("parameters");
                foreach (MethodWindow.MethodSettings.Parameter param in (myMethods[key] as MethodWindow).Settings.Parameters)
                {
                    XmlNode paramNode = myDocument.CreateElement("param");
                    XmlAttribute paramNameAttribute = myDocument.CreateAttribute("name");
                    XmlAttribute paramTypeAttribute = myDocument.CreateAttribute("type");
                    paramNameAttribute.InnerText = param.ParameterName;
                    paramTypeAttribute.InnerText = param.ParameterType;
                    paramNode.Attributes.Append(paramNameAttribute);
                    paramNode.Attributes.Append(paramTypeAttribute);
                    parametersNode.AppendChild(paramNode);
                }
                methodNode.AppendChild(parametersNode);
                XmlNode methodContentNode = myDocument.CreateElement("content");
                methodContentNode.InnerText = (myMethods[key] as MethodWindow).EditorText;
                methodNode.AppendChild(methodContentNode);
                rootNode.AppendChild(methodNode);
            }

            myDocument.AppendChild(rootNode);
            try
            {
                myDocument.Save(fileName);
                methodListForm.IsSaved = true;
            }
            catch (Exception ex)
            {
                new ExceptionMessageBox(ex);
            }
        }



        /// <summary>
        /// Einlesen einer Datei mit dem XmlParser.
        /// </summary>
        /// <param name="fileName">Dateiname</param>
        private void ReadCodeFromXMLFile(String fileName)
        {
            XmlDocument myDocument = new XmlDocument();
            myDocument.Load(fileName);
            XmlNode rootNode = myDocument.DocumentElement;
            XmlNode mainNode = myDocument.GetElementsByTagName("main")[0];
            mainMethodForm.EditorText = mainNode.InnerText;
            methodListForm.ClearAllMethods();

            foreach (XmlNode methodNode in myDocument.GetElementsByTagName("method"))
            {
                String methodName = methodNode.Attributes["methodName"].Value;
                String returnType = methodNode.Attributes["returnType"].Value;
                XmlNode parametersNode = methodNode["parameters"];
                List<MethodWindow.MethodSettings.Parameter> paramList = new List<MethodWindow.MethodSettings.Parameter>();
                foreach (XmlNode param in parametersNode.ChildNodes)
                {
                    paramList.Add(new MethodWindow.MethodSettings.Parameter { ParameterName = param.Attributes["name"].Value, ParameterType = param.Attributes["type"].Value });
                }
                methodListForm.AddMethod(methodName,methodNode["content"].InnerText,returnType, paramList);
            }

            methodListForm.IsSaved = true;

        }
        #endregion

        //Global Keybindings
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.F5)
            {
                if (!bCompiled) //noch nicht kompiliert
                {
                    compilerToolStripCompile_Click(this, null);
                }
                if (bCompiled)
                {
                    compilerToolStripRun_Click(this, null);
                }
            }
            if (keyData == (Keys.Control |Keys.T))
            {
                methodListForm.InvokeKeyPressButtonAddMethod();
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }


        #region ToolStripButtons für Dateiverwaltung

        private void editorToolStripUndo_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Source.CanUndo())
            {
                currentMethodForm.EditorBox.Source.Undo();
            }
        }

        private void editorToolStripRedo_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Source.CanRedo())
            {
                currentMethodForm.EditorBox.Source.Redo();
            }
        }

        private void editorToolStripDelete_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Selection.SelectionLength > 0)
            {
                currentMethodForm.EditorBox.Selection.Delete();
            }
        }

        private void editorToolStripCut_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Selection.CanCut())
            {
                currentMethodForm.EditorBox.Selection.Cut();
            }
        }

        private void editorToolStripCopy_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Selection.CanCopy())
            {
                currentMethodForm.EditorBox.Selection.Copy();
            }
        }

        private void editorToolStripPaste_Click(object sender, EventArgs e)
        {
            if (currentMethodForm.EditorBox.Selection.CanPaste())
            {
                currentMethodForm.EditorBox.Selection.Paste();
            }
        }

        private void fileToolStripNew_Click(object sender, EventArgs e)
        {
            menuDateiNeu_Click(sender, e);
        }

        private void fileToolStripOpen_Click(object sender, EventArgs e)
        {
            menuDateiOeffnen_Click(sender, e);
        }

        private void fileToolStripSave_Click(object sender, EventArgs e)
        {
            menuDateiSpeichern_Click(sender, e);
        }

        private void fileToolStripPrint_Click(object sender, EventArgs e)
        {
            menuDateiDrucken_Click(sender, e);
        }

        #endregion

    


    }

  
}
